iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 16
1
Mobile Development

程式初學:Android與Kotlin系列 第 16

Day 16--天氣app(二) retrofit

  • 分享至 

  • xImage
  •  

WeatheData的data class建立好之後
就可以用retrofit準備api了
複習retrofit

網路權限

AndroidManifest.xml加入

<uses-permission android:name="android.permission.INTERNET" />

gradle

dependencies加入

implementation "com.squareup.retrofit2:retrofit:2.3.0"
implementation "com.squareup.retrofit2:converter-gson:2.3.0"

Api interface

新增一個WeatherApiService.kt檔案

看一下我們之前拿到的request url
https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=rdec-key-123-45678-011121314

如果像此範例app只有要拿這一個資料,也可以把整個url放在interface的@GET中

不過通常專案會有多樣api需求,所以還是用良好一些的做法

建立Url常數

分析base網址應該是哪部分後,以const val宣告

private const val BASE_URL = "https://opendata.cwb.gov.tw/api/"

建立請求

api有多種常見請求方式@GET,@POST,@PUT,@DELETE等等
目前還是練習基本的@GET

新增名爲WeatherApiService的interface

interface WeatherApiService {
    @GET("v1/rest/datastore/F-C0032-001")
    fun getWeather(
        @Query("Authorization") key: String,
        @Query("locationName") city: String? = null
    ): Call<WeatherData>
}

裡面只有一個getWeather()函數,回傳一個以WeatherData爲Type的Call object

其中有二個以@Query註解的參數key,city

就是呼叫getWeather()時
將授權碼(key),城市名(city)作爲引數傳進去,再與@GET,@Query的參數一起
合併爲完整可取得api的網址

準備好後,就可建立一個api Object

object WeatherApi {
    private val retrofit = Retrofit.Builder()
        .addConverterFactory(GsonConverterFactory.create())
        .baseUrl(BASE_URL)
        .build()
    val retrofitService: WeatherApiService = retrofit.create(WeatherApiService::class.java)
}
  • 首先以Retrofit.Builder()產生一個Retrofit的物件
  • 呼叫.addConverterFactory,加入GsonConverterFactory.create()
    就是一個叫做Gson的轉換工具,功能是將Json轉成data class

    參考來源 / Gson教學
  • 呼叫.baseUrl,並將BASE_URL傳入,最後再呼叫.build()
  • 再以此retrofit物件呼叫.creat實作interface WeatherApiService

發起請求

全部設定好之後,就可以準備發起請求
這邊直接寫在MainActivity的onCreate()中執行

        WeatherApi
            .retrofitService
            .getWeather(key = "rdec-key-123-45678-011121314")
            .enqueue(object : retrofit2.Callback<WeatherData> {
                override fun onFailure(call: Call<WeatherData>, t: Throwable) {
                    Log.e("fail", t.message)
                }

                override fun onResponse(
                    call: Call<WeatherData>,
                    response: Response<WeatherData>
                ) {
                    //api response..
                    Log.d("success", response.toString())
                    if (response.isSuccessful) {
                        response.body()?.records?.location?.forEach {
                            Log.d("api", it.toString())
                        }
                    }
                }
            })

使用retrofitService呼叫getWeather,先傳入key
(因爲city宣告爲null,可選用,如果要用可傳入例如city="嘉義縣",這樣就只拿到嘉義縣的部分)
再呼叫.enqueue異步發起請求
並override onFailure,onResponse二個函數要執行的動作
啓動app後,檢視logcat看是否成功取得資料


上一篇
Day 15--天氣app(一) Open Data API,JSON
下一篇
Day 17--天氣app(三) viewPager2,TabLayout
系列文
程式初學:Android與Kotlin30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言